package com.cyw.common.annotations.support;

import com.cyw.common.annotations.CheckEnumLegal;
import lombok.extern.slf4j.Slf4j;

import javax.validation.ConstraintDeclarationException;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

import static com.cyw.common.utils.BaseUtils.isAnyNull;


/**
 * 枚举校验 校验器
 * @Author:cyw
 * @CreateTime: 2020/11/11 15:00
 **/
@Slf4j
public class CheckEnumLegalValidator implements ConstraintValidator<CheckEnumLegal, Object> {

    private Class<? extends Enum<?>> enumClass;
    private String enumMethod;


    @Override
    public void initialize(CheckEnumLegal constraintAnnotation) {
        enumClass = constraintAnnotation.enumClass();
        enumMethod = constraintAnnotation.checkLegalMethodName();
    }

    @Override
    public boolean isValid(Object value, ConstraintValidatorContext context) {

        if (isAnyNull(value, enumClass, enumMethod)) {
            return true;
        }

        Class<?> valueClass = value.getClass();

        try {
            Method method = enumClass.getMethod(enumMethod, valueClass);
            if (!Boolean.TYPE.equals(method.getReturnType()) && !Boolean.class.equals(method.getReturnType())) {
                throw new RuntimeException(enumClass + "类中" + enumMethod + "方法返回不是Boolean值");
            }

            if(!Modifier.isStatic(method.getModifiers())) {
                throw new RuntimeException(enumClass + "类中" + enumMethod + "方法不是静态方法");
            }
            method.setAccessible(true);
            Boolean result = (Boolean)method.invoke(null, value);
            return result == null ? false : result;
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            if (e instanceof InvocationTargetException){
                throw new ConstraintDeclarationException(((InvocationTargetException) e).getTargetException().getMessage());
            }
            throw new RuntimeException(e);
        }
    }
}

    
    
    
    
    
    
    
    
    

    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    